<html>
<head>
  <title></title>
</head>
<style type="text/css">
  body { margin: auto; width: 100%; }
  div { margin: 15; padding: 10; width: 100%; }
  textarea { margin: 10; padding: 10; width: 95%; height: 15%; font-size: 12; resize: none; }
  .button { margin: 10; padding: 10; width: 80%; height: 5%; font-size: 40; }
  .title { margin: 20; padding: 20; font-size: 42; font-weight: bold; }
  .subtitle { margin: 10; padding: 10; font-size: 32; }
  .text { font-size: 25; }
  .center { text-align: center; }
  .save { background-color: #FFFACD; }
  .update { background-color: #CAE1FF; }
  .find { background-color: #FFF0F5; }
  .remove { background-color: #F0FFF0; }
  .event { background-color:  #D1D1D1; }
</style>
<body>

<script>

// Features to test:
// 1. Save - by saving two new contacts and check by onchangechange event.
// 2. Contact change event - by checking if all new added IDs are received.
// 3. Update - by updating first contact.
// 4. Find - by looking for the updated contact and compare with expected result.
// 5. Remove - by removing the second contact.
// 6. Clear - by clearing all contacts and check if all contacts are removed.

window.onload = function() {
  var contacts = navigator.contacts || xwalk.experimental.contacts;

  contacts.addEventListener('contactschange', function(data) {
      var output = document.getElementById('event');
      output.value += 'contacts changes:\n';
      data.added && logEventListener('added: ', data.added, output);
      data.removed && logEventListener('removed: ', data.removed, output);
      data.modified && logEventListener('modified: ', data.modified, output);
      output.value += '-----------\n';
      output.scrollTop = output.scrollHeight;
  });

  // Helpers
  function setHTML(id, str) { document.getElementById(id).innerHTML = str; }
  function addHTML(id, str) { document.getElementById(id).innerHTML += str+'<br>'; }
  function ifcontains(a, e) { return a.indexOf(e) != -1; }
  function logContactSaved(contact) {
    addHTML('save', 'Contact ' + contact.id + ' ' + contact.name.givenNames[0] + ' ' + contact.name.familyNames[0] + ' saved!');
  }

  function errorCallback(error) {
    document.title = 'Fail';
    console.log(error);
  }

  var addedIDs = [];
  var testNewContactFlag = false;
  var expectedNewPhoneNumber = '+4455001';
  function testNewContacts() {
    // Test Case 3: update first contact after both contacts are saved.
    var output = 'Will update contact ' + 
                 contact1.id + ' ' +
                 contact1.name.givenNames[0] + ' ' +
                 contact1.name.familyNames[0] + ': phone from ' +
                 contact1.phoneNumbers[0].value + ' to ' + expectedNewPhoneNumber;
    addHTML('update', output);

    contact1.phoneNumbers[0].value = expectedNewPhoneNumber;
    contacts.save(contact1).then(updateCallback, errorCallback);
  }

  // Create two contacts for testing
  var givenName = 'John';

  var contactName1 = new ContactName({
    givenNames: [givenName],
    familyNames: ['Doe']
  });

  var contactName2 = new ContactName({
    givenNames: [givenName],
    familyNames: ['Smith']
  });

  var mobilePhone1 = new ContactTelField({
    types: ['home'],
    preferred: true,
    value: '+01234567890'
  });

  var mobilePhone2 = new ContactTelField({
    types: ['work'],
    preferred: false,
    value: '+11234567890'
  });

  // Test Case 1: Save two new contacts
  var contact1 = new Contact({
    name: contactName1,
    phoneNumbers: [mobilePhone1]
  });

  var contact2 = new Contact({
    name: contactName2,
    phoneNumbers: [mobilePhone2]
  });

  function handleSaveSuccessCallback(_contact, item) {
    addedIDs.push(item.id);
    logContactSaved(item);
    _contact.id = item.id; 
    // Test Case 2: check if oncontactchanges received all new contacts IDs.
    if (ifcontains(addedIDs, contact1.id) && ifcontains(addedIDs, contact2.id)) {
      testNewContactFlag = true;
      testNewContacts();
    }
  }

  contacts.save(contact1).then(function(item) {
      handleSaveSuccessCallback(contact1, item);
    }, 
    errorCallback);

  contacts.save(contact2).then(function(item) { 
      handleSaveSuccessCallback(contact2, item);
    }, 
    errorCallback);

  var testUpdateFirstFlag = false;
  function updateCallback(item) {
    var output = '<p>Contact ' + 
                 item.id + ' ' +
                 item.name.givenNames[0] + ' ' +
                 item.name.familyNames[0] + ' updated:<br>phone now is: ' +
                 item.phoneNumbers[0].value;
    addHTML('update', output);
    testUpdateFirstFlag = (item.phoneNumbers[0].value == expectedNewPhoneNumber);

    // Test Case 4: find first contact after it is updated.
    var ContactFindOptions = function(init) {
      this.value = init.value;
      this.operator = init.operator;
      this.fields = init.fields;
      this.sortBy = init.sortBy;
      this.sortOrder = init.sortOrder;
      this.resultsLimit = init.resultsLimit;
    }
    var options = new ContactFindOptions({
      value: contact1.name.familyNames[0],
      operator: 'contains',
      fields: ['familyName'],
      sortBy: ['familyNames'],
      sortOrder: 'ascending',
      resultsLimit: 3
    });
    contacts.find(options).then(findCallback, errorCallback);
  };

  var testFindFirstFlag = false;
  function findCallback(items) {
    testFindFirstFlag = (items[0].name.familyNames[0] == contact1.name.familyNames[0]);
    var output = 'Found '+items.length + ' contact(s):';
    output += '<p>';
    for (var i = 0, l = items.length; i < l; ++i) {
      output += items[i].name.givenNames[0] + ' ' + items[i].name.familyNames[0] + '<br>';
    }
    setHTML('find', output);

    // Test Case 5: remove specific contact.
    contacts.remove(contact2.id).then(removeCallback, errorCallback);
    addHTML('remove', "Will remove contact " + contact2.id);
  };

  function removeCallback() {
    addHTML('remove', contact2.id + " is removed.<br>Will test clear()");
    // Test Case 6: clear all contacts.
    contacts.clear().then(clearCallback, errorCallback);
  }

  // Check if contacts are all removed, which means all test steps are done. If so we verify all results.
  function clearCallback() {
    addHTML('remove', "All contacts are removed.");
    if (testNewContactFlag && testUpdateFirstFlag && testFindFirstFlag) {
      document.title = 'Pass';
    } else {
      document.title = 'Fail';
    }
  }

  function logEventListener(msg, data, output) {
    for (var i = 0; i < data.length; ++i) {
      msg += data[i] + '|';
    }
    output.value += msg + '\n';
  }

};

</script>

<div class="title center">Contacts API Example</div>

<div class="save">
  <p class="subtitle center">Save Contact</p>
  <p class="text center" id="save"></p>
</div>

<div class="update">
  <p class="subtitle center">Update Contact</p>
  <p class="text center" id="update"></p>
</div>

<div class="find">
  <p class="subtitle center">Find Contact</p>
  <p class="text center" id="find"></p>
</div>

<div class="remove">
  <p class="subtitle center">Remove Contact</p>
  <p class="text center" id="remove"></p>
</div>

<div class="event">
  <p class="subtitle center">Contact Event</p>
  <textarea id="event" readonly=true></textarea>
</div>

</body>
</html>
